home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / codeview.arc / CIRCLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-06-27  |  5.1 KB  |  249 lines

  1. #include <dos.h> 
  2. #include <conio.h> 
  3. #include <math.h>
  4.  
  5. #define SQUARE(root) ((root) * (root))
  6. #define ABS(num) (((num) < 0) ? (-num) : (num)) 
  7. #define PI 3.14159265
  8.  
  9. /* Function prototypes */ 
  10.  
  11. int  init (int);
  12. void dot ( int, int, int );
  13. int  isqrt ( int );
  14. void circle ( int, int, int, int );
  15. void palette ( int );
  16. void background ( int );
  17.  
  18. /* Arrays for storing address information for all pixels */ 
  19.  
  20. unsigned yaddr[200];
  21. unsigned xaddr[640];
  22. char shift[640];
  23. char point[640];
  24.  
  25. char far *scrn = (char far *)0xB8000000;    /* Screen buffer    */
  26.  
  27. int  max_x, max_y, max_clr, shifter, back = 3, pal = 1;
  28.  
  29. /*
  30.  * Use variables rather than constants for the following 
  31.  * values so we can change them in the debugger
  32.  */
  33.  
  34. int  aspect = 270, x_wid = 85, y_wid = 78;
  35.  
  36. main()
  37. {
  38.     int i, x, y, mode = 4, tmode, p = 1, b = 8;
  39.  
  40.     tmode = getmode();
  41.     init(mode);
  42.     background(b);
  43.     palette(p);
  44.     for (i = 0; i <= 90; ++i) {    /* Draw circles    */ 
  45.         x = x_wid * atan(sin(i / PI));
  46.         y = y_wid * atan(cos(i / PI));
  47.         circle((max_x / 2) + x,100 + y,i % 40,(i % max_clr) + 1);
  48.     }
  49.     for (i = 0; i <= 90; ++i) {    /* Erase them    */ 
  50.         x = x_wid * atan(sin(i / PI));
  51.         y = y_wid * atan(cos(i / PI));
  52.         circle((max_x / 2)+x,100+y,i % 40,0);
  53.     }
  54.     init(tmode);    /* Restore original mode    */
  55.     return(0);
  56. }
  57.  
  58. int getmode()
  59.  
  60. {
  61.     union REGS inregs, outregs;
  62.  
  63.     inregs.h.ah = 0x0F;    /* Use BIOS call to get mode    */
  64.  
  65.     inregs.h.al = 0; 
  66.     int86(0x10,&inregs,&outregs);
  67.     if (outregs.h.al == 7) {
  68.         puts("Can't run with monochrome adapter.\a");
  69.         exit(7);
  70.     }
  71.     else
  72.         return(outregs.h.al);
  73. }
  74.  
  75.  
  76. int init (num)
  77. int num;
  78. {
  79.     int indx = 0, indx2 = 0;
  80.     unsigned clr_wid, mask;
  81.     union REGS inregs, outregs;
  82.  
  83.     if (num > 6) {        /* Can't assign EGA modes    */ 
  84.                 /* (they could be added easily)    */
  85.         puts("Invalid mode.\x07");
  86.         exit(0);
  87.     }
  88.     switch (num) {
  89.     case 4 :                /* Set variables for each mode  */
  90.  
  91.         max_clr = 3;
  92.         max_x = 320;
  93.         max_y = 200;
  94.         shifter = 4;
  95.         clr_wid = 2;
  96.         break; 
  97.     case 5 : 
  98.         max_clr = 1;
  99.         max_x = 320;
  100.         max_y = 200;
  101.         shifter = 4;
  102.         clr_wid = 2;
  103.         break;
  104.     case 6 : 
  105.         max_clr = 1;
  106.         max_x = 640;
  107.         max_y = 200;
  108.         shifter = 8;
  109.         clr_wid = 1;
  110.         break;
  111.     }
  112.     if (num > 3) {            /* For graphics modes only,     */
  113.         while (indx < max_y) {    /* calculate all y offsets      */ 
  114.             yaddr[indx] = 80 * indx2;
  115.             ++indx; 
  116.             yaddr[indx] = (80 * indx2) + 0x2000;
  117.             ++indx; 
  118.             ++indx2; 
  119.         }
  120.                     /* Calculate all x offsets      */ 
  121.  
  122.         for (indx = 0; indx < max_x; ++indx) {
  123.             mask = 0x80 >> (clr_wid * (indx % shifter));
  124.  
  125.             if (num != 6) { /* Medium resolution offsets    */ 
  126.  
  127.                 mask |= (mask >> 1);
  128.                 shift[indx] = 6 - (clr_wid * (indx % shifter));
  129.             }
  130.             else            /* High resolution offsets    */ 
  131.  
  132.                 shift[indx] = 7 - (indx % shifter);
  133.             point[indx] = ~mask;
  134.             xaddr[indx] = indx / shifter;
  135.         }
  136.     }
  137.  
  138.     inregs.h.ah = 0;    /* Use BIOS call to set mode    */
  139.     inregs.h.al = num;
  140.     int86(0x10,&inregs,&outregs);
  141.     return(num);
  142. }
  143.  
  144. /* Draw a dot    */ 
  145.  
  146. void dot ( x, y, clr )
  147. int x, y, clr;
  148.  
  149. {
  150.     unsigned total;
  151.     char tcolor; 
  152.  
  153.     clr = ABS(clr) & max_clr;       /* Check color boundary */
  154.  
  155.     total = xaddr[x] + yaddr[y];    /* Put in screen buffer */
  156.  
  157.     scrn[total] = (clr << shift[x]) | (scrn[total] & point[x]);
  158. }
  159.  
  160. int isqrt ( arg )      /* Calculate integer square root  */ 
  161. int arg;               /* (real square root is too slow) */
  162.  
  163.  
  164. {
  165.     int odd_int, old_arg, first_sqrt; 
  166.  
  167.     odd_int = 1;          /* Initialize with 1              */
  168.  
  169.     old_arg = arg;        /* Save argument                  */
  170.  
  171.     while (arg >= 0) {    /* Find double approximate root   */ 
  172.         arg = arg - odd_int;
  173.         odd_int = odd_int + 2;
  174.     }
  175.     first_sqrt = odd_int >> 1;      /* Divide by two        */
  176.  
  177.  
  178.     /* Return adjusted root */ 
  179.     if (SQUARE(first_sqrt) - first_sqrt + 1 > old_arg)
  180.         return(first_sqrt - 1);
  181.     else 
  182.         return(first_sqrt);
  183. }
  184.  
  185. void circle ( cx, cy, radius, clr )
  186. int cx, cy, radius, clr;
  187.  
  188. {
  189.     int a, af, b, bf, target, r2, temp;
  190.  
  191.     clr = ABS(clr) & max_clr;       /* Check color boundary */
  192.  
  193.     target = 0; 
  194.     a = radius; 
  195.     b = 0; 
  196.     r2 = SQUARE(radius);
  197.     while (a >= b) {                /* Calculate new point  */ 
  198.         b = isqrt(r2 - SQUARE(a));
  199.         temp = target; 
  200.         target = b; 
  201.         b = temp; 
  202.  
  203.         while (b < target) {    /* Plot point in each   */ 
  204.                                 /* quadrant             */ 
  205.             af = max_x * a / aspect;
  206.             bf = max_x * b / aspect;
  207.             dot(cx + af,cy + b,clr); 
  208.             dot(cx + bf,cy + a,clr);
  209.             dot(cx - af,cy + b,clr); 
  210.             dot(cx - bf,cy + a,clr);
  211.             dot(cx - af,cy - b,clr); 
  212.             dot(cx - bf,cy - a,clr);
  213.             dot(cx + af,cy - b,clr); 
  214.             dot(cx + bf,cy - a,clr);
  215.             b = b + 1;
  216.         }
  217.         a = a - 1;
  218.     }
  219. }
  220.  
  221. void palette ( color )
  222. int color;
  223.  
  224. {
  225.     union REGS inregs, outregs;
  226.  
  227.     color &= 0x01;
  228.     inregs.h.ah = 0x0B;     /* Call BIOS to set palette     */
  229.  
  230.     inregs.h.bh = 1;
  231.     inregs.h.bl = color; 
  232.     int86(0x10,&inregs,&outregs);
  233. }
  234.  
  235. void background ( color )
  236. int color;
  237.  
  238. {
  239.     union REGS inregs, outregs;
  240.  
  241.     color &= 0x0F; 
  242.     inregs.h.ah = 0x0B;     /* Call BIOS to set background  */
  243.  
  244.     inregs.h.bh = 0;
  245.     inregs.h.bl = color;
  246.     int86(0x10,&inregs,&outregs);
  247. }         
  248.  
  249.